﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using aspProject;
using aspProject.LabelService;

namespace aspProject
{
    public partial class MainPage : UserControl
    {
        private string[] imagesOnServer = {"../Images/img1.jpg",
                               "../Images/img2.jpg",
                               "../Images/img3.jpg"};

        private bool isDragDropInEffect = false;
        private UIElement currentElement = null;
        private List<UIElement> componentsConfig = new List<UIElement>();
        private Point pos;
        private int count = 0;
        List<BitmapImage> images = new List<BitmapImage>();
        private LabelServiceClient proxy = new LabelServiceClient("BasicHttpBinding_ILabelService");
        private ICollection<LabelTypeDetail> labelTypeDetails;
        private LabelTypeDetail currentLabelType;
        private IList<FieldConfigDetail> fieldConfigs = new List<FieldConfigDetail>();

        public MainPage()
        {
            InitializeComponent();

            proxy.GetLabelTypesCompleted += new EventHandler<GetLabelTypesCompletedEventArgs>(proxy_GetLabelTypesCompleted);
            proxy.GetLabelTypesAsync();
            foreach (UIElement uiEle in workCanvas.Children)
            {
                uiEle.MouseMove += new MouseEventHandler(Element_MouseMove);
                uiEle.MouseLeftButtonDown += new MouseButtonEventHandler(Element_MouseLeftButtonDown);
                uiEle.MouseLeftButtonUp += new MouseButtonEventHandler(Element_MouseLeftButtonUp);
            }


            int index = 0;
            foreach (string img in imagesOnServer)
            {
                Image currentImg = new Image();
                Uri currentUri = new Uri(img, UriKind.Relative);
                BitmapImage currentBMI = new BitmapImage(currentUri);
                currentImg.Source = currentBMI;

                RowDefinition rowdef = new RowDefinition();
                rowdef.Height = new GridLength(60);
                ThemesGrid.RowDefinitions.Add(rowdef);

                Button currentButton = new Button();
                currentButton.Name = "imageSelectionButton_" + index;
                currentButton.Content = currentImg;
                currentButton.Click += new RoutedEventHandler(clickImageButton);
                currentButton.SetValue(Grid.RowProperty, index);
                ThemesGrid.Children.Add(currentButton);

                index++;
            }
        }

        private void clickImageButton(object sender, RoutedEventArgs e)
        {
            string buttonName = ((Button)sender).Name;
            int underscoreIndex = buttonName.LastIndexOf('_');
            string sub = buttonName.Substring(underscoreIndex + 1);
            int idx = int.Parse(sub);

            Uri currentUri = new Uri(imagesOnServer[idx], UriKind.Relative);
            BitmapImage currentBMI = new BitmapImage(currentUri);
            backgroundimage.Source = currentBMI;
            //backgroundimage.Visibility = Visibility.Visible;
        }

        void proxy_GetLabelTypesCompleted(object sender, GetLabelTypesCompletedEventArgs e)
        {
            labelTypeDetails = e.Result;
            this.comboBoxLabelTypes.ItemsSource = labelTypeDetails;
            this.comboBoxLabelTypes.SelectionChanged +=
                new SelectionChangedEventHandler(comboBoxLabelTypes_SelectionChanged);
            
        }

        void comboBoxLabelTypes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            currentLabelType = (LabelTypeDetail) comboBoxLabelTypes.SelectedItem;
        }



        // After the Frame navigates, ensure the HyperlinkButton representing the current page is selected
        private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
        {
            foreach (UIElement child in LinksStackPanel.Children)
            {
                HyperlinkButton hb = child as HyperlinkButton;
                if (hb != null && hb.NavigateUri != null)
                {
                    if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
                    {
                        VisualStateManager.GoToState(hb, "ActiveLink", true);
                    }
                    else
                    {
                        VisualStateManager.GoToState(hb, "InactiveLink", true);
                    }
                }
            }
        }

        // If an error occurs during navigation, show an error window
        private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            e.Handled = true;
            ChildWindow errorWin = new ErrorWindow(e.Uri);
            errorWin.Show();
        }


        void Element_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragDropInEffect)
            {
                FrameworkElement currEle = sender as FrameworkElement;
                
                // Retrieving the item's current x and y position
                double xPos = e.GetPosition(null).X - pos.X;
                double yPos = e.GetPosition(null).Y - pos.Y;

                // Bind Element within the field of the canvas.
                double newXpos = xPos + (double)currEle.GetValue(Canvas.LeftProperty);
                double newYpos = yPos + (double)currEle.GetValue(Canvas.TopProperty);
                double canvasXpos = (double)workCanvas.GetValue(Canvas.LeftProperty);
                double canvasYpos = (double)workCanvas.GetValue(Canvas.TopProperty);
                double elementWidth = (double)currEle.Width;
                double elementHeight = (double)currEle.Height;
                double canvasWidth = (double)workCanvas.ActualWidth;
                double canvasHeight = (double)workCanvas.ActualHeight;



                /*if (newXpos >= 0 && newYpos >= 0 && newXpos <= (canvasXpos+canvasWidth) - elementWidth
                    && newYpos <= (canvasYpos + canvasHeight) - elementHeight)*/
                {
                    bool zomgX = true;
                    bool zomgY = true;
                    //info.Content = "mouse: "+e.GetPosition(null).X+","+e.GetPosition(null).Y+"   canvas X:"+canvasXpos+"  newXpos:"+newXpos;
                    if (newXpos < canvasXpos)
                    {
                        newXpos = canvasXpos;
                        zomgX = false;
                    }
                    if (newYpos < canvasYpos)
                    {
                        newYpos = canvasYpos;
                        zomgY = false;
                    }
                    if (newXpos > (canvasXpos + canvasWidth) - elementWidth)
                    {
                        newXpos = (canvasXpos + canvasWidth) - elementWidth;
                        zomgX = false;
                    }
                    if (newYpos > (canvasYpos + canvasHeight) - elementHeight)
                    {
                        newYpos = (canvasYpos + canvasHeight) - elementHeight;
                        zomgY = false;
                    }



                    // Re-position Element

                    currEle.SetValue(Canvas.TopProperty, newYpos);
                    currEle.SetValue(Canvas.LeftProperty, newXpos);

                    double newMouseX = pos.X;
                    double newMouseY = pos.Y;
                    if (zomgX)
                    {
                        // Reset the new position value
                        //pos = new Point(e.GetPosition(null).X, pos.Y);//e.GetPosition(null);
                        newMouseX = e.GetPosition(null).X;
                    }
                    if(zomgY)
                    {
                        //pos = new Point(pos.X, e.GetPosition(null).Y);
                        newMouseY = e.GetPosition(null).Y;
                    }
                    pos = new Point(newMouseX, newMouseY);
                }
            }
        }


        void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement fEle = sender as FrameworkElement;
            currentElement = fEle;
            heightValueLabel.Text = currentElement.DesiredSize.Height.ToString();
            widthValueLabel.Text = currentElement.DesiredSize.Width.ToString();

            if (currentElement is Border)
            {

                contentValueLabel.Text = ((TextBlock)((Border)currentElement).Child).Text;
                fontSizeValueLabel.Text = ((TextBlock)((Border)currentElement).Child).FontSize.ToString();
                isDragDropInEffect = true;
                // x and y coords of mouse pointer position
                pos = e.GetPosition(null);
                // Enable mouse capture on element
                fEle.CaptureMouse();
                // Set the cursor to 'Hand' when mouse pointer is over element
                fEle.Cursor = Cursors.Hand;

            }
        }


        void Element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {

            if (isDragDropInEffect)
            {
                FrameworkElement ele = sender as FrameworkElement;
                isDragDropInEffect = false;
                // Removes Mouse Capture from Element being dragged
                ele.ReleaseMouseCapture();
                ele.Cursor = Cursors.Arrow;

                //infolbl.Content = "" + (double)workCanvas.GetValue(Width);
                
            }
        }

        private void createComponent_Click(object sender, RoutedEventArgs e)
        {

            createBlock(count.ToString(), 30, 200, 20, 20, 16, "");
            
        }

        private void createBlock(String name, int height, int width, double posTop, double posLeft, int font, String text)
        {
            Border blockBorder = new Border();
            blockBorder.Name = "b " + name;
            blockBorder.Height = height;
            blockBorder.Width = width;
            
            blockBorder.SetValue(Canvas.LeftProperty, posLeft);
            blockBorder.SetValue(Canvas.TopProperty, posTop);
            blockBorder.BorderThickness = new Thickness(1);
            blockBorder.BorderBrush = new SolidColorBrush(Colors.Black);

            TextBlock newTextBlock = new TextBlock();
            newTextBlock.Name = name;
            newTextBlock.FontSize = font;
            newTextBlock.Text = text;

            
            blockBorder.Child = newTextBlock;
            workCanvas.Children.Add(blockBorder);
            


            blockBorder.MouseMove += new MouseEventHandler(Element_MouseMove);
            blockBorder.MouseLeftButtonDown += new MouseButtonEventHandler(Element_MouseLeftButtonDown);
            blockBorder.MouseLeftButtonUp += new MouseButtonEventHandler(Element_MouseLeftButtonUp);

            componentsConfig.Add(blockBorder);

            count++;
        }

        private void switchButton_Click(object sender, RoutedEventArgs e)
        {
            if(switchButton.Content.ToString() == "Themes")
            {
                switchButton.Content = "Properties";
                propertiesGrid.Visibility = Visibility.Collapsed;
                ThemesGrid.Visibility = Visibility.Visible;
            }
            else
            {
                switchButton.Content = "Themes";
                propertiesGrid.Visibility = Visibility.Visible;
                ThemesGrid.Visibility = Visibility.Collapsed;
            }
        }

        private void applyChangesButton_Click(object sender, RoutedEventArgs e)
        {
            update();
        }

        private FileInfo uploadFileInfo;
        private void uploadThemeButton_Click(object sender, RoutedEventArgs e)
        {
            if (uploadFileInfo == null)
            {
                //Open File Dialog
                OpenFileDialog dlg = new OpenFileDialog();
                //The _FilterText variable used to control file extentions
                //supported by the Upload control
                dlg.Filter = "JPEG Files|*.jpg";
                bool? result = dlg.ShowDialog();
                if (result.HasValue && result.Value)
                {
                    this.uploadFileInfo = dlg.File;
                    //The _FileSize variable used to control the
                    //Maximum Size supported by the control.
                    /*if (this.uploadFileInfo.Length > this._FileSize)
                    {
                        //Control will fire a FileSizeError event, if the
                        //Uploading File Size greater than the specified.
                        if (this._onFileSizeError != null)
                        {
                            this._onFileSizeError(this, EventArgs.Empty);
                        }
                        return;
                    }
                    this.txtFileName.Text = this.uploadFileInfo.Name;*/
                }

            }
            else
            {
                byte[] buffer = new byte[this.uploadFileInfo.Length];
                using (Stream s = this.uploadFileInfo.OpenRead())
                {
                    //Reading the File Content to the Stream.
                    //It is using a WCF Service with Upload File method
                    s.Read(buffer, 0, buffer.Length);

                    
                    //Service.Service1Client client = new ServiceReference1.Service1Client();
                    //client.UploadFileCompleted 
                    //    += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_UploadFileCompleted);
                    //client.UploadFileAsync(this.uploadFileInfo.Name, buffer);
                }

            }
            /*OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "JPEG Files|*.jpg";

            if (openFileDialog.ShowDialog() == true)
            {
                Stream stream = (Stream)openFileDialog.File.OpenRead();
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, (int)stream.Length);
                BitmapImage bi = new BitmapImage();
                bi.SetSource(stream);
                Image Myimage = new Image();
                Myimage.Source = bi;
                string fileName = openFileDialog.File.Name;
            }*/
        }


        private void update()
        {
            currentElement.SetValue(HeightProperty, double.Parse(heightValueLabel.Text));

            currentElement.SetValue(WidthProperty, double.Parse(widthValueLabel.Text));

            ((TextBlock)((Border)currentElement).Child).Text = contentValueLabel.Text;

            ((TextBlock)((Border)currentElement).Child).FontSize = double.Parse(fontSizeValueLabel.Text);
        }

        private void propertiesGrid_KeyDown(object sender, KeyEventArgs e)
        {
         if(e.Key == Key.Enter)
         {
             update();
         }
        }

        private void propertiesGrid_KeyUp(object sender, KeyEventArgs e)
        {
            update();
        }

        private void Load_Click(object sender, RoutedEventArgs e)
        {
 
            proxy.GetFieldConfigsCompleted += new EventHandler<GetFieldConfigsCompletedEventArgs>(proxy_GetFieldConfigsCompleted);
            proxy.GetFieldConfigsAsync(currentLabelType.labelTypeId);
        }

        void proxy_GetFieldConfigsCompleted(object sender, GetFieldConfigsCompletedEventArgs e)
        {
            fieldConfigs.Clear();
            fieldConfigs = (IList<FieldConfigDetail>) e.Result;

            this.comboboxFieldConfig.ItemsSource = fieldConfigs;
            Debug.WriteLine("jimmy is ne noob");
        }

        private void deleteButton_Click(object sender, RoutedEventArgs e)
        {
            componentsConfig.Remove(currentElement);
            workCanvas.Children.Remove(currentElement);
            currentElement = null;
            heightValueLabel.Text = "";
            widthValueLabel.Text = "";
            contentValueLabel.Text = "";
            fontSizeValueLabel.Text = "";
        }
        private void loadConfig(FieldConfigContract fieldConfigContract)
        {
            //List<ComponentContract> components = fieldConfigContract.Components;
            //foreach (var component in components)
            //{
            //    createBlock(component.Id.ToString(), component.Height, component.Width, component.positionTop, component.positionLeft, component.fontSize, component.text);
            //}
        }

        private List<ComponentContract> convertConfig()
        {
            List<ComponentContract> components = new List<ComponentContract>();
            foreach (var element in componentsConfig)
            {
                ComponentContract component = new ComponentContract();
                component.Height = (int)element.DesiredSize.Height;
                component.Width = (int) element.DesiredSize.Width;
                component.Id = Int32.Parse(((TextBlock) ((Border) element).Child).Name);
                component.positionLeft = (double)element.GetValue(Canvas.LeftProperty);
                component.positionTop = (double)element.GetValue(Canvas.TopProperty);
                component.fontSize = (int)((TextBlock) ((Border) element).Child).FontSize;
                component.text = ((TextBlock)((Border)element).Child).Text;


                components.Add(component);
            }
            return components;
        }

        private void colorTextChanged(object sender, SelectionChangedEventArgs e)
         {
             ((TextBlock)((Border)currentElement).Child).Foreground = new SolidColorBrush(GetThisColor(((ListBoxItem)textColorValueLabel.SelectedItem).Content.ToString()));
         }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            FieldConfigDetail currentFieldConf = (FieldConfigDetail) comboboxFieldConfig.SelectedItem;
            proxy.GetFieldConfigCompleted += new EventHandler<GetFieldConfigCompletedEventArgs>(proxy_GetFieldConfigCompleted);
            proxy.GetFieldConfigAsync(currentFieldConf);
        }

        void proxy_GetFieldConfigCompleted(object sender, GetFieldConfigCompletedEventArgs e)
        {
            //e.Result
        }

        public Color GetThisColor(string colorString)
        {
            Type colorType = (typeof(System.Windows.Media.Colors));
            if (colorType.GetProperty(colorString) != null)
            {
                object o = colorType.InvokeMember(colorString,
                BindingFlags.GetProperty, null, null, null); if (o != null)
                {
                    return (Color)o;
                }
            }
            return Colors.Orange;
        }
       
    }


}